package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.Service.AccessTokenService;
import com.example.pojo.Article;
import com.example.pojo.BaseMsg;
import com.example.pojo.NewsMsg;
import com.example.pojo.TextMsg;
import com.example.util.HttpUtils;
import com.thoughtworks.xstream.XStream;
import javafx.beans.value.ObservableDoubleValue;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

@RestController
public class WeChatCheckController {
    private static final Logger LOGGER = LoggerFactory.getLogger(WeChatCheckController.class);

    @Autowired
    AccessTokenService accessTokenService;

    /**
     * 开发者通过检验signature对请求进行校验
     *
     * @param request  request
     * @param response response
     * @return String
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        System.out.println(request);
        try {
            // 微信加密签名
            String signature = request.getParameter("signature");
            // 时间戳
            String timestamp = request.getParameter("timestamp");
            // 随机数
            String nonce = request.getParameter("nonce");
            // 随机字符串
            String echostr = request.getParameter("echostr");
            PrintWriter out = response.getWriter();
            // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                out.print(echostr);
            } else {
                //校验失败返回其他
                out.print(timestamp);
            }
            out.close();
        } catch (Exception e) {
            LOGGER.error("微信服务器校验失败，失败信息：", e);
        }
    }

    /**
     * 接受消息
     */
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        Map<String, String> map = parseRequest(request.getInputStream());
        System.out.println(map);
        //处理完将响应一个xml给用户
        String respXml = getRespose(map);
        System.out.println(respXml);
        response.getWriter().print(respXml);
    }

    /**
     * 网页授权
     */
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    public void getUserInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1.用户同意授权，获取code
        String code = request.getParameter("code");
        LOGGER.info(code);
        //2.通过code获取网页授权的access_token
        String url = " https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        url = url.replace("APPID", Constant.APP_ID).replace("CODE", code).replace("SECRET", Constant.APP_SECRET);
        LOGGER.info(url);
        String string = HttpUtils.sendGet(url);
        JSONObject jsonObject = JSONObject.parseObject(string);
        String accessToken = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        //3.刷新access_token（如果需要）
        //4.通过token获取用户信息
        String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        getUserInfoUrl = getUserInfoUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);
        String userInfoJsonStr = HttpUtils.sendGet(getUserInfoUrl);
        System.out.println(userInfoJsonStr);
    }


    public static Map<String, String> parseRequest(InputStream is) {
        Map<String, String> map = new HashMap<String, String>();
        //1.通过io流得到文档对象
        SAXReader saxReader = new SAXReader();
        Document document = null;
        try {
            document = saxReader.read(is);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //2.通过文档对象得到根节点对象
        Element root = document.getRootElement();
        //3.通过根节点对象获取所有子节点对象
        List<Element> elements = root.elements();
        //4.将所有节点放入map
        for (Element element : elements) {
            map.put(element.getName(), element.getStringValue());
        }
        return map;
    }

    private String getRespose(Map<String, String> map) {
        BaseMsg msg = null;
        // 根据用户发送消息的类型,做不同的处理
        String msgType = map.get("MsgType");
        switch (msgType) {
            case "text":
                msg = dealTextMsg(map);
                break;
            case "news":
                break;
            default:
                break;
        }
        // System.out.println(msg);
        // 将处理结果转化成xml的字符串返回
        if (null != msg) {
            return beanToXml(msg);
        }
        return null;


    }

    private BaseMsg dealTextMsg(Map<String, String> map) {
        // 获取用户发送的消息内容
        String msg = map.get("Content");
        // 如果是图文回复一个图文消息
        if (msg.equals("图文")) {
            List<Article> articles = new ArrayList<Article>();
            Article article = new Article();
            article.setTitle("文章标题");
            article.setDescription("吃葡萄不吐葡萄皮");
            article.setPicUrl("www.baidu.com");
            article.setUrl("www.konglong.com");
            articles.add(article);
            return new NewsMsg(map, articles);
        }
        /**
         * 网页授权登录
         */
        if(msg.equals("登录")){
          String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE#wechat_redirect";
          String REDIRECT_URI="http://liangdan.natapp1.cc/getUserInfo";
          url = url.replace("APPID", Constant.APP_ID).replace("REDIRECT_URI",REDIRECT_URI).replace("SCOPE","snsapi_userinfo");
            return new TextMsg(map, "点击<a href=\""+url+"\">这里</a>登录");
        }
        //否则回复一个文本消息,文本内容为'当前时间+你好'
        //当然这个内容可以自定义,在这里也可以接入自动回复机器人
        TextMsg textMsg = new TextMsg(map, new Date(System.currentTimeMillis()).toLocaleString() + "你好");
        return textMsg;
    }

    /**
     * 把bean对象转换为XML形式
     */
    private String beanToXml(BaseMsg msg) {
        XStream stream = new XStream();
        stream.processAnnotations(TextMsg.class);
        stream.processAnnotations(NewsMsg.class);
        String xml = stream.toXML(msg);
        return xml;
    }



}
